package com.blue.spring.redis;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterOutputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class FastjsonRedisSerializer implements RedisSerializer<Object>
{
	private static Logger logger = LoggerFactory.getLogger(FastjsonRedisSerializer.class);
	
	private static SerializerFeature[] serializer = new SerializerFeature[]
			{SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteClassName};
	
	private static Feature[] feature = new Feature[] {};
	
	private boolean zip = false; // 是否压缩
	
	public FastjsonRedisSerializer()
	{
	}

	@Override
	public byte[] serialize(Object t) throws SerializationException
	{
		if (t == null)
			return null;
		
		byte[] bytes = JSON.toJSONBytes(t, serializer);
		if (zip) // 压缩
		{
			bytes = this.zip(bytes);
		}
		return bytes;
	}
	
	private byte[] zip(byte[] data)
	{
		if (data == null || data.length == 0)
			return data;
		
		byte[] output = null;
		try (ByteArrayOutputStream baos = new ByteArrayOutputStream(data.length);
				DeflaterOutputStream dos = new DeflaterOutputStream(baos))
		{
			dos.write(data, 0, data.length);
			dos.finish();
			dos.flush();
			output = baos.toByteArray();
		}
		catch (IOException e)
		{
			logger.error("压缩流出错－", e);
		}
		
		return output;
	}

	@Override
	public Object deserialize(byte[] bytes) throws SerializationException
	{
		if (bytes == null || bytes.length == 0)
			return null;
		
		if (zip)
		{
			bytes = this.unzip(bytes);
		}
		Object obj = JSON.parse(bytes, feature);
		return obj;
	}

	private byte[] unzip(byte[] data)
	{
		byte[] output = null;
		try (ByteArrayOutputStream baos = new ByteArrayOutputStream(data.length);
				InflaterOutputStream ios = new InflaterOutputStream(baos))
		{
			ios.write(data, 0, data.length);
			ios.finish();
			ios.flush();
			output = baos.toByteArray();
		}
		catch (IOException e)
		{
			logger.error("解压缩流出错－", e);
		}
		
		return output;
	}

	public void setZip(boolean zip)
	{
		this.zip = zip;
	}
	
}
